﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ESoft.Core.Data.Service;
using ESoft.Core.Utils.Extensions;
using ESoft.Core.Web.VO;
using ESoft.Portal.Data.Domain.Entity;
using Microsoft.Extensions.Caching.Memory;

namespace ESoft.Portal.Areas.ContentManager.Data.Service.Impl
{
    public class ChannelService : IChannelService
    {
        private readonly IMemoryCache _memoryCache;
        private readonly IBaseService _baseService;

        public ChannelService(IBaseService baseService, IMemoryCache memoryCache)
        {
            _baseService = baseService;
            _memoryCache = memoryCache;
        }

        public void Update(dynamic input, string channelId, User user)
        {
            CRichTextEntity richText = new CRichTextEntity();
            string fullDetail = input.fullDetail;
            richText.TextContent = System.Text.Encoding.Default.GetBytes(fullDetail);
            _baseService.Add(richText);

            CContentChannelEntity channel = new CContentChannelEntity();
            channel.FatherChannelId = input.fatherChannelId;
            channel.OrgId = user.ShopId;
            channel.ChannelName = input.channelName;
            channel.ChannelType = input.channelType;
            channel.CreateDatetime = DateTime.Now;
            channel.ImageId = input.imageId;
            channel.IsHot = input.isHot;
            channel.RichTextId = richText.RichTextId;
            channel.Sort = input.sort;
            channel.Url = input.url;
            channel.ChannelId = channelId;
            _baseService.Update(channel);
            RemoveCache();
        }

        private void RemoveCache()
        {
            _memoryCache.Remove("ALLChannel");
        }

        public void Add(dynamic input, User user)
        {
            CRichTextEntity richText = new CRichTextEntity();
            string fullDetail = input.fullDetail;
            richText.TextContent = System.Text.Encoding.Default.GetBytes(fullDetail);
            _baseService.Add(richText);

            CContentChannelEntity channel = new CContentChannelEntity
            {
                FatherChannelId = input.fatherChannelId,
                OrgId = user.ShopId,
                ChannelName = input.channelName,
                ChannelType = input.channelType,
                CreateDatetime = DateTime.Now,
                ImageId = input.imageId,
                IsHot = input.isHot,
                RichTextId = richText.RichTextId,
                Sort = input.sort,
                Url = input.url,
                IsLock = 2
            };
            _baseService.Add(channel);
            RemoveCache();
        }

        public void Delete(string channelId)
        {
            List<CContentChannelEntity> children = GetAllChannel(channelId);
            if (children.Any())
            {
                throw new Exception("删除失败！存在下级栏目！");
            }

            if (this._baseService.QueryEntities<CContentArticleEntity>(x => x.ChannelId.In(children.Select(k => k.ChannelId).ToList())).Any())
            {
                throw new Exception("删除失败！栏目下存在文章信息！");
            }

            var channel = _baseService.Find<CContentChannelEntity>(channelId);
            if (channel.IsLock == 1)
            {
                throw new Exception("该栏目已锁定，不能删除！");
            }
            _baseService.Delete(channel);
            RemoveCache();
        }

        public List<CContentChannelEntity> GetAllChannel(string channelId)
        {
            var channelList = CacheAllChannel();
            return GetAllChannel(channelId, channelList);
        }

        public List<CContentChannelEntity> CacheAllChannel()
        {
            var channelList = _memoryCache.GetOrCreate<List<CContentChannelEntity>>("ALLChannel", (x) =>
            {
                var list = this._baseService.QueryEntities<CContentChannelEntity>();
                x.SetValue(list);
                return list;
            });
            return channelList;
        }

        private List<CContentChannelEntity> GetAllChannel(string channelId, List<CContentChannelEntity> channelList)
        {
            var nextChannelList = new List<CContentChannelEntity>();
            if (channelList.Any(x => x.FatherChannelId == channelId))
            {
                foreach (var channel in channelList.Where(x => x.FatherChannelId == channelId))
                {
                    nextChannelList.Add(channel);
                    nextChannelList.AddRange(GetAllChannel(channel.ChannelId, channelList));
                }
            }
            return nextChannelList;
        }
    }
}
